/**
 * 
 */
package com.imooc.security.core.social.qq.connet;

import org.springframework.social.oauth2.AbstractOAuth2ServiceProvider;

import com.imooc.security.core.social.qq.api.QQ;
import com.imooc.security.core.social.qq.api.QQImpl;

/**
 * QQ互联文档:http://wiki.connect.qq.com/
 *
 * ServiceProvider需要服务提供商Api接口实现和OAuth2Operations接口实现
 * ServiceProvider负责处理的流程:
 * 1.用户导向认证服务器
 * 2.用户同意授权
 * 3.返回Client并携带授权码
 * 4.申请令牌
 * 5.发放令牌
 * 6.获取用户信息
 */
public class QQServiceProvider extends AbstractOAuth2ServiceProvider<QQ> {

	private String appId;


	/***  用户授权地址用于获取授权码(code) == 1.用户导向认证服务器
	 * response_type	必须 	授权类型，此值固定为“code”。
	 * client_id	必须	 	申请QQ登录成功后，分配给应用的appid。
	 * redirect_uri	必须	 	成功授权后的回调地址，必须是注册appid时填写的主域名下的地址。注意需要将url进行URLEncode。
	 * state	必须	 	client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
	 * scope	可选 	请求用户授权时向用户显示的可进行授权的列表。例如：scope=get_user_info,list_album,upload_pic,do_like
	 * 可填写的值是API文档中列出的接口，以及一些动作型的授权（目前仅有：do_like），如果要填写多个接口名称，请用逗号隔开。
	 * 不传则默认请求对接口get_user_info进行授权。
	 * display	可选		仅PC网站接入时使用。不传则默认展示为PC下的样式，如果传入“mobile”，则展示为mobile端下的样式
	 */
	private static final String URL_AUTHORIZE = "https://graph.qq.com/oauth2.0/authorize";


	/***	用户获取access_token地址 == 4.申请令牌
	 * 请求参数
	 * grant_type	必须		授权类型，在本步骤中，此值为“authorization_code”。
	 * client_id	必须		申请QQ登录成功后，分配给网站的appid。
	 * client_secret	必须		申请QQ登录成功后，分配给网站的appkey。
	 * code	必须		上一步返回的authorization code。
	 *
	 * 如果用户成功登录并授权，则会跳转到指定的回调地址，并在URL中带上Authorization Code。
	 * 例如，回调地址为www.qq.com/my.php，则跳转到：http://www.qq.com/my.php?code=520DD95263C1CFEA087******
	 * code会在10分钟内过期。
	 * redirect_uri	必须	与上面一步中传入的redirect_uri保持一致。
	 *
	 *
	 * 若返回成功则可获得：access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14
	 * access_token	授权令牌，Access_Token。
	 * expires_in	该access token的有效期，单位为秒。
	 * refresh_token	在授权自动续期步骤中，获取新的Access_Token时需要提供的参数。
	 */
	private static final String URL_ACCESS_TOKEN = "https://graph.qq.com/oauth2.0/token";
	
	public QQServiceProvider(String appId, String appSecret) {
		//初始化父类中的OAuth2Operations的属性为QQOAuth2Template
		super(new QQOAuth2Template(appId, appSecret, URL_AUTHORIZE, URL_ACCESS_TOKEN));
		this.appId = appId;
	}

	/**
	 * 获取服务提供商的接口实现实例，QQImpl是一个多实例的类不能加入到容器中
	 * @param accessToken
	 * @return
	 */
	@Override
	public QQ getApi(String accessToken) {
		return new QQImpl(accessToken, appId);
	}

}
